package com.testing.sunnyserver.controller;

import com.testing.sunnycommon.model.Result;
import com.testing.sunnycommon.service.DistributionRunService;
import com.testing.sunnyserver.model.RunInfoBO;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.cluster.specifyaddress.Address;
import org.springframework.web.bind.annotation.*;
import org.I0Itec.zkclient.ZkClient;
import org.apache.dubbo.rpc.cluster.specifyaddress.UserSpecifiedAddressUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Classname DistributionRunController
 * @Description 类型说明
 * @Date 2023/7/14 20:37
 * @Created by 特斯汀Roy
 */
@RestController
@RequestMapping("/disRun")
public class DistributionRunController {
    @DubboReference
    DistributionRunService distributionRunService;

    private List<String> clients = new ArrayList<>();


    @PostMapping("/onClient")
    public Result runOnClient(@RequestBody RunInfoBO runInfo) {
        //先更新当前的客户端列表，判断传入的列表是否都在客户端之内
        getClients();
        if (!clients.containsAll(runInfo.getClientsList())) {
            return Result.fail(1060, "调用客户端执行失败，您选择的客户端列表中有已经下线的，请检查", runInfo.getClientsList());
        }
        //遍历需要执行的客户端列表，每个客户端都去进行调用
        for (String client : runInfo.getClientsList()) {
            //使用单点连接插件提供的方法，设置要调用的生产者的地址
            UserSpecifiedAddressUtil.setAddress(new Address(URL.valueOf(client)));
            //实现不同的client的调用
            distributionRunService.runOnClient(runInfo.getProjectId());
        }
        return Result.success("已通知客户端执行自动化测试");
    }

    @GetMapping("/clients")
    public Result getClients() {
        //创建zkClient对象
        ZkClient zkClient = new ZkClient("192.168.253.1:2181");
        //获取其中providers下的内容,通过拼接路径来进行获取
        List<String> children = zkClient.getChildren("/dubbo/" + DistributionRunService.class.getName() + "/providers");
        System.out.println("原始的children是" + children);
        //需要的只是其中的ip+端口，通过正则表达式来进行匹配
        Pattern ipPortPattern = Pattern.compile("dubbo%3A%2F%2F(.*?)%3A(.*?)%2Fcom.testing.sunnycommon");
        List<String> clients = new ArrayList<>();
        children.forEach(child -> {
            Matcher matcher = ipPortPattern.matcher(child);
            if (matcher.find()) {
                String ip = matcher.group(1);
                String port = matcher.group(2);
                clients.add(ip + ":" + port);
            }
        });
        //赋值给成员变量，供调用执行的时候获取客户端列表
        this.clients = clients;
        return Result.success(clients);
    }


}
